
import { Solar, Lunar, EightChar } from 'lunar-typescript'


export interface 生辰 {
  类型: "公历" | "农历",
  年:number,
  月:number,
  日:number,
  时:number,
  分?:number,
  秒?:number
}

export type 阴阳 = "阳" | "阴" | "";
export type 五行 = "木" | "火" | "土" | "金" | "水" | "";
export interface 柱 {
  天干: string;
  地支: string;
  纳音: string;
  藏干: string[];
  天干十神: string;
  地支十神: string[];
  地势: string;
  天干阴阳: 阴阳;
  天干五行: 五行;
  地支阴阳: 阴阳;
  地支五行: 五行;
}


function 获取天干地支阴阳(天干地支: string): 阴阳 {
  const 阴阳Map: { [key: string]: 阴阳 } = {
    // 天干
    '甲': '阳', '乙': '阴',
    '丙': '阳', '丁': '阴',
    '戊': '阳', '己': '阴',
    '庚': '阳', '辛': '阴',
    '壬': '阳', '癸': '阴',
    // 地支
    '子': '阳', '丑': '阴',
    '寅': '阳', '卯': '阴',
    '辰': '阳', '巳': '阴',
    '午': '阳', '未': '阴',
    '申': '阳', '酉': '阴',
    '戌': '阳', '亥': '阴'
  };
  return 阴阳Map[天干地支] || '';
}
function 获取天干地支五行(天干地支: string): 五行 {
  const 五行Map: { [key: string]: 五行 } = {
    // 天干
    '甲': '木', '乙': '木',
    '丙': '火', '丁': '火',
    '戊': '土', '己': '土',
    '庚': '金', '辛': '金',
    '壬': '水', '癸': '水',
    // 地支
    '子': '水', '丑': '土',
    '寅': '木', '卯': '木',
    '辰': '土', '巳': '火',
    '午': '火', '未': '土',
    '申': '金', '酉': '金',
    '戌': '土', '亥': '水'
  };
  return 五行Map[天干地支] || '';
}


export function 排盘(
  性别: "男" | "女",
  生辰: 生辰,
  获取小运: boolean = true,
  获取流年: boolean = true,
  流派: 1 | 2 = 2
) {
  let lunar: Lunar;
  if (生辰.类型 === "公历") {
    lunar = Solar
      .fromYmdHms(
        生辰.年,
        生辰.月,
        生辰.日,
        生辰.时 || 12,
        生辰.分 || 0,
        生辰.秒 || 0
      ).getLunar();
  } else {
    lunar = Lunar.fromYmdHms(
      生辰.年,
      生辰.月,
      生辰.日,
      生辰.时 || 12,
      生辰.分 || 0,
      生辰.秒 || 0
    );
  }
  if (!lunar) {
    throw new Error("错误的日期");
  }

  const 八字 = EightChar.fromLunar(lunar);
  if (八字 && 流派) {
    八字.setSect(流派);
  }

  const 年柱: 柱 = {
    天干: 八字.getYearGan(),
    地支: 八字.getYearZhi(),
    纳音: 八字.getYearNaYin(),
    藏干: 八字.getYearHideGan(),
    天干十神: 八字.getYearShiShenGan(),
    地支十神: 八字.getYearShiShenZhi(),
    地势: 八字.getYearDiShi(),
    天干阴阳: 获取天干地支阴阳(八字.getYearGan()),
    天干五行: 获取天干地支五行(八字.getYearGan()),
    地支阴阳: 获取天干地支阴阳(八字.getYearZhi()),
    地支五行: 获取天干地支五行(八字.getYearZhi()),
  };
  const 月柱: 柱 = {
    天干: 八字.getMonthGan(),
    地支: 八字.getMonthZhi(),
    纳音: 八字.getMonthNaYin(),
    藏干: 八字.getMonthHideGan(),
    天干十神: 八字.getMonthShiShenGan(),
    地支十神: 八字.getMonthShiShenZhi(),
    地势: 八字.getMonthDiShi(),
    天干阴阳: 获取天干地支阴阳(八字.getMonthGan()),
    天干五行: 获取天干地支五行(八字.getMonthGan()),
    地支阴阳: 获取天干地支阴阳(八字.getMonthZhi()),
    地支五行: 获取天干地支五行(八字.getMonthZhi()),
  };
  const 日柱: 柱 = {
    天干: 八字.getDayGan(),
    地支: 八字.getDayZhi(),
    纳音: 八字.getDayNaYin(),
    藏干: 八字.getDayHideGan(),
    天干十神: 八字.getDayShiShenGan(),
    地支十神: 八字.getDayShiShenZhi(),
    地势: 八字.getDayDiShi(),
    天干阴阳: 获取天干地支阴阳(八字.getDayGan()),
    天干五行: 获取天干地支五行(八字.getDayGan()),
    地支阴阳: 获取天干地支阴阳(八字.getDayZhi()),
    地支五行: 获取天干地支五行(八字.getDayZhi()),
  };
  const 时柱: 柱 = {
    天干: 八字.getTimeGan(),
    地支: 八字.getTimeZhi(),
    纳音: 八字.getTimeNaYin(),
    藏干: 八字.getTimeHideGan(),
    天干十神: 八字.getTimeShiShenGan(),
    地支十神: 八字.getTimeShiShenZhi(),
    地势: 八字.getTimeDiShi(),
    天干阴阳: 获取天干地支阴阳(八字.getTimeGan()),
    天干五行: 获取天干地支五行(八字.getTimeGan()),
    地支阴阳: 获取天干地支阴阳(八字.getTimeZhi()),
    地支五行: 获取天干地支五行(八字.getTimeZhi()),
  };

  const 运 = 八字.getYun(性别 === '女' ? 0 : 1, 八字.getSect());
  const 起运 = `${运.getStartYear()}年${运.getStartMonth()}月${运.getStartDay()}日${运.getStartHour()}时后起运`;
  const 原大运列表 = 运.getDaYun().slice(1);
  const 大运列表 = [];
  const 流年列表 = [];
  for (const item of 原大运列表) {
    // 获取流年
    if (获取流年) {
      for (const 流年 of item.getLiuNian()) {
        // const 流月列表 = [];
        // for (const 流月 of 流年.getLiuYue()) {
        //   流月列表.push({
        //     月份: 流月.getMonthInChinese(),
        //     干支: 流月.getGanZhi(),
        //     旬: 流月.getXun(),
        //     旬空: 流月.getXunKong(),
        //   })
        // }
        流年列表.push({
          年份: 流年.getYear(),
          年龄: 流年.getAge(),
          干支: 流年.getGanZhi(),
          旬: 流年.getXun(),
          旬空: 流年.getXunKong(),
          // 流月列表,
        });
      }
    }
    
    // 获取大运
    大运列表.push({
      开始年份: item.getStartYear(),
      结束年份: item.getEndYear(),
      开始年龄: item.getStartAge(),
      结束年龄: item.getEndAge(),
      干支: item.getGanZhi(),
      小运: 获取小运 ? item.getXiaoYun().map(xy => {
        return {
          年份: xy.getYear(),
          年龄: xy.getAge(),
          干支: xy.getGanZhi(),
        };
      }) : [],
      旬: item.getXun(),
      旬空: item.getXunKong(),
    });
  }

  return {
    生辰,
    八字: 八字.getYear() + 八字.getMonth() + 八字.getDay() + 八字.getTime(),
    年柱,
    月柱,
    日柱,
    时柱,
    起运,
    大运列表,
    流年列表,
    文本: `
      性别：${性别}
      生辰：${生辰.类型}${生辰.年}年${生辰.月}月${生辰.日}日${生辰.时}时${生辰.分}分
      八字：${八字.getYear()} ${八字.getMonth()} ${八字.getDay()} ${八字.getTime()}
      四柱信息：
      1. 年柱（${年柱.天干}${年柱.地支}）
      - 天干${年柱.天干}${获取天干地支五行(年柱.天干)}（${获取天干地支阴阳(年柱.天干)}）：${年柱.天干十神}
      - 地支${年柱.地支}${获取天干地支五行(年柱.地支)}（${获取天干地支阴阳(年柱.地支)}）：${年柱.地支十神.join('、')}
      - 纳音：${年柱.纳音}
      - 藏干：${年柱.藏干.join('、')}
      2. 月柱（${月柱.天干}${月柱.地支}）
      - 天干${月柱.天干}${获取天干地支五行(月柱.天干)}（${获取天干地支阴阳(月柱.天干)}）：${月柱.天干十神}
      - 地支${月柱.地支}${获取天干地支五行(月柱.地支)}（${获取天干地支阴阳(月柱.地支)}）：${月柱.地支十神.join('、')}
      - 纳音：${月柱.纳音}
      - 藏干：${月柱.藏干.join('、')}
      3. 日柱（${日柱.天干}${日柱.地支}）
      - 天干${日柱.天干}${获取天干地支五行(日柱.天干)}（${获取天干地支阴阳(日柱.天干)}）：${日柱.天干十神}
      - 地支${日柱.地支}${获取天干地支五行(日柱.地支)}（${获取天干地支阴阳(日柱.地支)}）：${日柱.地支十神.join('、')}
      - 纳音：${日柱.纳音}
      - 藏干：${日柱.藏干.join('、')}
      4. 时柱（${时柱.天干}${时柱.地支}）
      - 天干${时柱.天干}${获取天干地支五行(时柱.天干)}（${获取天干地支阴阳(时柱.天干)}）：${时柱.天干十神}
      - 地支${时柱.地支}${获取天干地支五行(时柱.地支)}（${获取天干地支阴阳(时柱.地支)}）：${时柱.地支十神.join('、')}
      - 纳音：${时柱.纳音}
      - 藏干：${时柱.藏干.join('、')}

      大运：
      ${起运}
      ${大运列表.map(dy => `- ${dy.开始年份}至${dy.结束年份}（${dy.开始年龄}岁至${dy.结束年龄}岁）：${dy.干支}`).join('\n')}

      ${获取小运 ? "小运：" : ""}
      ${大运列表.map(dy => dy.小运.map(xy => `  - ${xy.年份}年（${xy.年龄}岁）：${xy.干支}`).join('\n')).join('\n')}

      ${获取流年 ? "流年：" : ""}
      ${流年列表.map(ln => `- ${ln.年份}年（${ln.年龄}岁）：${ln.干支}`).join('\n')}
    `.replace(/^\s+/gm, '').trim()
  };
}

